package com.pan.admin.module.datareport.service.impl;

import com.pan.admin.module.datareport.dao.DataReportDao;
import com.pan.admin.module.datareport.entity.AmountVO;
import com.pan.admin.module.datareport.entity.ApplyAndPushVO;
import com.pan.admin.module.datareport.entity.CostVO;
import com.pan.admin.module.datareport.entity.PushVO;
import com.pan.admin.module.datareport.entity.RechargeVO;
import com.pan.admin.module.datareport.entity.RevenueDataVO;
import com.pan.admin.module.datareport.entity.RevenueVO;
import com.pan.admin.module.datareport.entity.StartTimeAndEndTime;
import com.pan.admin.module.datareport.entity.StockVO;
import com.pan.admin.module.datareport.service.DataReportService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 数据报表
 *
 * @author caoxin
 */
@Service
public class DataReportServiceImpl implements DataReportService {

    @Autowired
    private DataReportDao dataReportDao;

    @Override
    @Transactional(readOnly = true)
    public List<ApplyAndPushVO> applyAndPush(StartTimeAndEndTime startTimeAndEndTime, List<Long> loanChannelId) {
        startTimeAndEndTime.ifNullGen1();
        List<LocalDate> dayList = startTimeAndEndTime.dayList();

        List<StockVO> stockList = this.dataReportDao.listStock(startTimeAndEndTime, loanChannelId);
        List<PushVO> pushList = this.dataReportDao.listPush(startTimeAndEndTime, loanChannelId);

        List<ApplyAndPushVO> ApplyAndPushList = dayList.stream().map(day -> {
            StockVO stock = stockList.stream().filter(item -> item.createTime().isEqual(day)).findFirst()
                    .orElse(new StockVO(day, 0));
            PushVO push = pushList.stream().filter(item -> item.createTime().isEqual(day)).findFirst()
                    .orElse(new PushVO(day, 0));
            return new ApplyAndPushVO(day, stock.total() + push.total(), stock.total(), push.total());
        }).collect(Collectors.toList());

        return ApplyAndPushList;
    }

    @Override
    @Transactional(readOnly = true)
    public List<Map<String, Object>> planCityDistributionSituation(Boolean limit) {
        return this.dataReportDao.listPlanCityDistributionSituation(limit);
    }

    @Override
    @Transactional(readOnly = true)
    public List<Map<String, Object>> loanProductBalanceSituation(Boolean desc) {
        return this.dataReportDao.listLoanProductBalanceSituation(desc);
    }

    @Override
    @Transactional(readOnly = true)
    public List<RevenueDataVO> revenueData(StartTimeAndEndTime startTimeAndEndTime, List<Long> loanChannelId, List<Long> loanProductId) {
        startTimeAndEndTime.ifNullGen1();
        List<LocalDate> dayList = startTimeAndEndTime.dayList();

        List<RevenueVO> revenueList = this.dataReportDao.listRevenue(startTimeAndEndTime, loanChannelId, loanProductId);
        List<CostVO> costList = this.dataReportDao.listCost(startTimeAndEndTime, loanChannelId, loanProductId);

        List<RevenueDataVO> revenueDataList2 = dayList.stream().map(day -> {
            RevenueVO revenue = revenueList.stream().filter(item -> item.createTime().isEqual(day)).findFirst()
                    .orElse(new RevenueVO(day, BigDecimal.ZERO));
            CostVO cost = costList.stream().filter(item -> item.createTime().isEqual(day)).findFirst()
                    .orElse(new CostVO(day, BigDecimal.ZERO));
            // 利润 = 收益 - 成本
            BigDecimal profit = revenue.amount().subtract(cost.amount());
            return new RevenueDataVO(day, cost.amount(), revenue.amount(), profit);
        }).collect(Collectors.toList());

        return revenueDataList2;
    }

    @Override
    @Transactional(readOnly = true)
    public List<RechargeVO> recharge(StartTimeAndEndTime startTimeAndEndTime, List<Long> loanProductId) {
        startTimeAndEndTime.ifNullGen1();
        List<LocalDate> dayList = startTimeAndEndTime.dayList();

        List<RechargeVO> rechargeList = this.dataReportDao.listRecharge(startTimeAndEndTime, loanProductId);

        List<RechargeVO> rechargeList2 = dayList.stream().map(day -> {
            return rechargeList.stream().filter(item -> item.createTime().isEqual(day)).findFirst()
                    .orElse(new RechargeVO(day, BigDecimal.ZERO));
        }).collect(Collectors.toList());

        return rechargeList2;
    }

    @Override
    @Transactional(readOnly = true)
    public List<AmountVO> amount(StartTimeAndEndTime startTimeAndEndTime, List<Long> loanProductId) {
        startTimeAndEndTime.ifNullGen1();
        List<LocalDate> dayList = startTimeAndEndTime.dayList();

        List<AmountVO> amountList = this.dataReportDao.listAmount(startTimeAndEndTime, loanProductId);

        List<AmountVO> amountList2 = dayList.stream().map(day -> {
            return amountList.stream().filter(item -> item.createTime().isEqual(day)).findFirst()
                    .orElse(new AmountVO(day, BigDecimal.ZERO));
        }).collect(Collectors.toList());

        return amountList2;
    }
}
